home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / gems / g_gemsi.lha / GraphicsGems / PolyScan / fancytest.c next >
Encoding:
C/C++ Source or Header  |  1992-04-10  |  3.2 KB  |  121 lines

  1.  
  2.  
  3. /*
  4.  * fancytest.c: subroutine illustrating the use of poly_clip and poly_scan
  5.  * for Phong-shading and texture mapping.
  6.  * Note: lines enclosed in angle brackets "<", ">" should be 
  7.  * replaced with the code described.
  8.  * Makes calls to hypothetical packages "shade", "image", "texture",   
  9.  * "zbuffer".
  10.  * Paul Heckbert    Dec 1989
  11.  */
  12.  
  13. #include <stdio.h>
  14. #include <math.h>
  15. #include "poly.h"
  16.  
  17. #define XMAX 1280    /* hypothetical image width */
  18. #define YMAX 1024    /* hypothetical image height */
  19. #define LIGHT_INTEN 255        /* light source intensity */
  20.  
  21. void pixelproc();
  22.  
  23. fancytest()
  24. {
  25.     int i;
  26.     double WS[4][4];    /* world space to screen space transform */
  27.     Poly p;        /* a polygon */
  28.     Poly_vert *v;
  29.  
  30.     static Poly_box box = {0, XMAX-1, 0, YMAX-1, -32678, 32767};
  31.     /* 3-D screen clipping box */
  32.  
  33.     static Window win = {0, 0, XMAX-1, YMAX-1};
  34.     /* 2-D screen clipping window */
  35.     /*
  36.     <initialize world space position (x,y,z), normal (nx,ny,nz), and
  37.     texture position (u,v) at each vertex of p; set p.n>
  38.     <set WS to world-to-screen transform>
  39.     */
  40.  
  41.     /* transform vertices from world space to homogeneous */
  42.     /*   screen space */
  43.     for (i=0; i<p.n; i++) {
  44.         v = &p.vert[i];
  45.         mx4_transform(v->x, v->y, v->z, 1., 
  46.             WS, &v->sx, &v->sy, &v->sz, &v->sw);
  47.     }
  48.  
  49.  
  50.     /* interpolate sx, sy, sz, sw, nx, ny, nz, u, v in poly_clip */
  51.     p.mask = POLY_MASK(sx) | POLY_MASK(sy) | POLY_MASK(sz) |             POLY_MASK(sw) | POLY_MASK(nx) | POLY_MASK(ny) | POLY_MASK(nz) |
  52.         POLY_MASK(u) | POLY_MASK(v);
  53.  
  54.     poly_print("before clipping", &p);
  55.     if (poly_clip_to_box(&p, &box) == POLY_CLIP_OUT)    /* clip polygon */
  56.         return;                        /* quit if off-screen */
  57.  
  58.     /* do homogeneous division of screen position, texture position */
  59.     for (i=0; i<p.n; i++) {
  60.         v = &p.vert[i];
  61.         v->sx /= v->sw;
  62.         v->sy /= v->sw;
  63.         v->sz /= v->sw;
  64.         v->u /= v->sw;
  65.         v->v /= v->sw;
  66.         v->q = 1./v->sw;
  67.     }
  68.     /*
  69.      * previously we ignored q (assumed q=1),
  70.      *  henceforth ignore sw (assume sw=1)
  71.      * Interpolate sx, sy, sz, nx, ny, nz, u, v, q in poly_scan
  72.      */
  73.     p.mask &= ~POLY_MASK(sw);
  74.     p.mask |= POLY_MASK(q);
  75.  
  76.     poly_print("scan converting the polygon", &p);
  77.     poly_scan(&p, &win, pixelproc);    /* scan convert! */
  78. }
  79.  
  80. static void pixelproc(x, y, pt)    
  81.     /* called at each pixel by poly_scan */
  82. int x, y;
  83. Poly_vert *pt;
  84. {
  85.     int sz, u, v, inten;
  86.     double len, nor[3], diff, spec;
  87.  
  88.  
  89.     sz = pt->sz;
  90.     if (sz < zbuffer_read(x, y)) {
  91.         len = sqrt(pt->nx*pt->nx + pt->ny*pt->ny + pt->nz*pt->nz);
  92.         nor[0] = pt->nx/len;        /* unitize the normal vector */
  93.         nor[1] = pt->ny/len;
  94.         nor[2] = pt->nz/len;
  95.         shade(nor, &diff, &spec);    
  96.                         /* compute specular and diffuse coeffs*/
  97.         u = pt->u/pt->q;        /* do homogeneous div. of texture pos */
  98.         v = pt->v/pt->q;
  99.         inten = texture_read(u, v)*diff + LIGHT_INTEN*spec;
  100.         image_write(x, y, inten);
  101.         zbuffer_write(x, y, sz);
  102.     }
  103. }
  104.  
  105. /* mx4_transform: transform 4-vector p by matrix m */
  106. /*  yielding q: q = p*m */
  107.  
  108. mx4_transform(px, py, pz, pw, m, qxp, qyp, qzp, qwp)
  109. double px, py, pz, pw, m[4][4], *qxp, *qyp, *qzp, *qwp;
  110. {
  111.     *qxp = px*m[0][0] + py*m[1][0] + pz*m[2][0] + pw*m[3][0];
  112.     *qyp = px*m[0][1] + py*m[1][1] + pz*m[2][1] + pw*m[3][1];
  113.     *qzp = px*m[0][2] + py*m[1][2] + pz*m[2][2] + pw*m[3][2];
  114.     *qwp = px*m[0][3] + py*m[1][3] + pz*m[2][3] + pw*m[3][3];
  115. }
  116.  
  117.  
  118.  
  119.  
  120.  
  121.